/**
******************************************************************************************
* @file Spreader.c
* @brief Warn by TCP/IP all the rest of clients when one of them ask for a reset or a thresholds change.
* @date 19 mai 2015
* @author Benjamin LANCINOT
******************************************************************************************/
/* COPYRIGHT *****************************************************************************
******************************************************************************************
* Copyright (c) 2015, Audrey LOISEAU and Benjamin LANCINOT.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
*    list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************************/

#include "Spreader.h"

/*******************************************************************************************
* PROTOTYPES
********************************************************************************************/

void Spreader_addActiveProxy(Spreader*, int);

void Spreader_deleteProxy(Spreader*, int);

void Spreader_warnAllClient(Spreader*, int, char *, int);

void Spreader_destroyUtilities(Spreader *);

void Spreader_destroy(Spreader **);

void Spreader_destroy(Spreader **);

/********************************************************************************************
* FUNCTIONS
********************************************************************************************/

/**
 * @brief Constructor
 * @return new pointer to Spreader
 */
Spreader* Spreader_create(ProxyTab ** proxyAdress){
	Spreader* This = ( Spreader*) malloc(sizeof(*This));

        This->addActiveProxy = Spreader_addActiveProxy;
	This->deleteProxy = Spreader_deleteProxy;
	This->warnAllClient = Spreader_warnAllClient;

        This->activeProxyTab = calloc ( 1 , sizeof(int) );
        This->nbActif = 0;
        This->proxyTabAdress = proxyAdress;

	return This;
}

/**
 * @brief Add indice of a proxyTab for an active client
 * @param This Pointer to the wanted Spreader
 * @param id The id of the new active proxyTab
 **/
void Spreader_addActiveProxy(Spreader* This, int id){
	This->nbActif ++;
        This->activeProxyTab = realloc (This->activeProxyTab, This->nbActif* sizeof(int) );
	This->activeProxyTab[This->nbActif-1] = id;
        printf("add\n");
}

/**
 * @brief Remove indice of a proxyTab for an inactive client
 * @param This Pointer to the wanted Spreader
 * @param id The id of the inactive proxyTab
 **/
void Spreader_deleteProxy(Spreader* This, int id){
	int i;
        for (i = id; i < This->nbActif; i++) {
		This->activeProxyTab[i] = This->activeProxyTab[i+1];
	}
	This->nbActif --;
        This->activeProxyTab = realloc (This->activeProxyTab, This->nbActif* sizeof(int) );
        printf("delete\n");
}

/**
 * @brief Ask to concrete proxyTab to warn client about a changing. Only active clients without the client which give the information are notificated about this changing.
 * @param This Pointer to the wanted Spreader
 * @param cmd The type of command like a threshold of sound for exemple
 * @param message Char sequences with the message
 * @param socket The socket of the client which give the information
 **/
void Spreader_warnAllClient(Spreader* This, int cmd, char * message, int socket){
	int i;
        if (cmd >= 0 && cmd <5){
		for (i = 0; i < This->nbActif; i++) {
			if (socket != This->proxyTabAdress[This->activeProxyTab[i]]->sender->clientSocket)
			{
				This->proxyTabAdress[This->activeProxyTab[i]]->notifyBySpreader(This->proxyTabAdress[This->activeProxyTab[i]], cmd+8, message);
			}
		}
	}
}

/**
 * @brief Destroy all of the components of ProxyTab
 * @param This Pointer to the wanted ProxyTab
 **/
void Spreader_destroyUtilities(Spreader *This){
	free( This->activeProxyTab);

}

/**
 * @brief Destructor
 * @param This Double pointer need to be destruct
 */
void Spreader_destroy(Spreader **This){
	Spreader_destroyUtilities(*This);
        if (*This) {
        	free(*This);
		*This = NULL;
	}
}

